package com.itheima.service.mongo.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.StrUtil;
import com.itheima.domain.mongo.*;
import com.itheima.domain.vo.PageBeanVo;
import com.itheima.service.mongo.MovementService;
import com.itheima.util.ConstantUtil;
import org.apache.dubbo.config.annotation.DubboService;
import org.apache.yetus.audience.InterfaceAudience;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.ArrayList;
import java.util.List;


@DubboService
public class MovementServiceImpl implements MovementService {

    /*用于操作mongo数据库*/
    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private RedisIDService redisIDService;


    //发布动态
    @Override
    public void saveMovement(Movement movement) {
        /*
        * 插入动态：
        * 动态详情表movement，
        * 个人动态表MyMovement，
        * 好友动态表FriendMovement
        * 查询好友表，Friend
        * */
        //利用redis自增器给pid赋值
        // 插入movement
        //插入MyMovement，由于没有对应表，需要自己指定表，而save方法，可以用两个参数来建立指定表与实体类的对应关系。
        //从好友表中得到朋友id
        //插入好友的好友动态表


        Long pid = redisIDService.getNextId(ConstantUtil.MOVEMENT_ID);
        movement.setPid(pid);
        mongoTemplate.save(movement);

        ObjectId publishId = movement.getId();
        MyMovement myMovement = new MyMovement();
        myMovement.setPublishId(publishId);
        myMovement.setCreated(movement.getCreated());
        mongoTemplate.save(myMovement,ConstantUtil.MOVEMENT_MINE+movement.getUserId());

        Query query = new Query(Criteria.where("userId").is(movement.getUserId()));
        List<Friend> myFriends = mongoTemplate.find(query, Friend.class);

        if (CollectionUtil.isNotEmpty(myFriends)) {
            for (Friend friend : myFriends) {
                Long friendId = friend.getFriendId();
                FriendMovement friendMovement = new FriendMovement();
                friendMovement.setPublishId(publishId);
                friendMovement.setUserId(movement.getUserId());
                friendMovement.setCreated(movement.getCreated());
                mongoTemplate.save(friendMovement,ConstantUtil.MOVEMENT_FRIEND+friendId);
            }
        }
    }


    //查询我的动态
    @Override
    public PageBeanVo findMyMovement(Long userId, Integer pageNum, Integer pageSize) {
        /*
        * mongoDB中的分页都是使用query的方法来进行查询的，并没有Mysql中的分页插件一说
        * */
        /*
        * 1、分页
        * 2、查出所有的动态详情
        * 3、构建PageBeanVo
        * */

        Integer index = (pageNum-1)*pageSize ;
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created")))  //排序
                .skip(index).limit(pageSize);  //分页
        List<MyMovement> myMovements = mongoTemplate.find(query, MyMovement.class, ConstantUtil.MOVEMENT_MINE + userId);

        ArrayList<Movement> movements = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(myMovements)){
            for (MyMovement myMovement : myMovements) {
                Movement movement = mongoTemplate.findById(myMovement.getPublishId(), Movement.class);
                //判断审核条件
                if (movement.getState() == 1){
                    movements.add(movement);
                }
            }
        }

        //TOD 看眼视频，他是怎么说的
        //这里的count查的是所有，相当与count（*） ，query是条件，写null和query，都是一样的结果
        long count = mongoTemplate.count(query, MyMovement.class, ConstantUtil.MOVEMENT_MINE + userId);
        return new PageBeanVo(pageNum,pageSize,count,movements);
    }


    //查询好友动态
    @Override
    public PageBeanVo findFriendMovement(Long userId, Integer pageNum, Integer pageSize) {
        Integer index = (pageNum-1)*pageSize;

        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created")))
                .skip(index).limit(pageSize);
        List<FriendMovement> friendMovements = mongoTemplate.find(query, FriendMovement.class, ConstantUtil.MOVEMENT_FRIEND + userId);

        ArrayList<Movement> movements = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(friendMovements)){
            for (FriendMovement friendMovement : friendMovements) {
                ObjectId publishId = friendMovement.getPublishId();
                Movement movement = mongoTemplate.findById(publishId, Movement.class);
                if(movement.getState() == 1) {
                    movements.add(movement);
                }
            }
        }

        long count = mongoTemplate.count(new Query(), FriendMovement.class, ConstantUtil.MOVEMENT_FRIEND + userId);

        return new PageBeanVo(pageNum , pageSize , count ,movements);
    }


    //查看推荐动态
    @Override
    public PageBeanVo findRecommendMovement(Long userId, Integer pageNum, Integer pageSize) {
        Integer index = (pageNum - 1) *pageSize;
        Query query = new Query(Criteria.where("userId").is(userId))
                .with(Sort.by(Sort.Order.desc("score")))
                .skip(index).limit(pageSize);
        List<RecommendMovement> recommendMovements = mongoTemplate.find(query, RecommendMovement.class);

        ArrayList<Movement> movements = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(recommendMovements)){
            for (RecommendMovement recommendMovement : recommendMovements) {
                Movement movement = mongoTemplate.findById(recommendMovement.getPublishId(), Movement.class);
                if (movement.getState() == 1) {
                    movements.add(movement);
                }
            }
        }

        long count = mongoTemplate.count(query, RecommendMovement.class);

        return new PageBeanVo(pageNum , pageSize , count , movements);
    }

    @Override
    public Movement findById(String publishId) {
        return mongoTemplate.findById(new ObjectId(publishId), Movement.class);
    }

    //动态查询我的动态
    @Override
    public PageBeanVo findMyMovementByPage(Long userId, String state, Integer pageNum, Integer pageSize) {

        Integer index = (pageNum - 1)*pageSize;
        Query query = new Query().with(Sort.by(Sort.Order.desc("created"))).skip(index).limit(pageSize);

        //动态添加userId
        if (userId != null) {
            query.addCriteria(Criteria.where("userId").is(userId));
        }

        //动态添加state,
        if ( !("''".equals(state) || "".equals(state))) {
            query.addCriteria(Criteria.where("state").is(Integer.parseInt(state)));
        }

        List<Movement> movementList = mongoTemplate.find(query, Movement.class);

        long count = mongoTemplate.count(query, Movement.class);
        return new PageBeanVo(pageNum,pageSize,count,movementList);
    }

    //更新审核结果
    @Override
    public void updateMovementById(Movement movement) {
        mongoTemplate.save(movement);
    }
}
